/* Script for type checking. Type check is made in two phase. User key presses
   are controlled. So Only one coma can be in decimal numbers and only one minus
   mark in the front of the number. The length of the string is controlled as
   the user writes it.
   In the second phase the value is checked against the given range. This happens
   when the field loses focus. If auto adjust is set then the value is adjusted.
 */

function isInteger(val){
    for (var i = 0; i < val.length; i++){
        var ch = val.charAt(i);
        if (((ch < "0") || (ch > "9"))) return false;
    }

    return true;
} // isInteger

function daysInFebruary(year){
    /* Return 29 if given year is leap year. Otherwice 28. */
    var result = ((year % 4 == 0) && !(year % 100 == 0)) ||
                 (year % 400 == 0) ? 29 : 28;
    return result
} // daysInFebruary


function replaceNonNumbers(str) {
    var result = "";
    /* Change all delimiters to period */
    for (i = 0; i < str.length; i++){
        var c = str.charAt(i);
        if ((c < "0") || (c > "9")) { result += "."; }
        else { result += c; }
    }

    return result;
} // replaceNonNumbers


/* Checks date's validy. Style parameter is:
    "e" -> dd.mm.yyyy
    "j" -> yyyy.mm.dd
    "m" -> mm.dd.yyyy
    The fields are separated with one non number character
*/
function checkDate(Date, Style) {
    /* The first 0 is to put the month index right. The index is one based. */
    var daysInMonth = Array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    Date = replaceNonNumbers(Date)
    /* Extract the fields */
    var fields = Date.split(".");

    /* Is more than three fields not a valid date stamp */
    if (fields.Length > 3) return false                 // <-- EXIT!!

    Style = Style.toLowerCase();
    switch (Style) {
        case "j":
            var year_ind = 0;
            var month_ind = 1;
            var day_ind = 2;
            break;

        case "m":
            var month_ind = 0;
            var day_ind = 1;
            var year_ind = 2;
            break;

        default:
            var day_ind = 0;
            var month_ind = 1;
            var year_ind = 2;
    } // switch
    day = fields[day_ind];
    month = fields[month_ind];
    year = fields[year_ind];

    day = parseInt(day);
    month = parseInt(month);
    year = parseInt(year);

    /* Check for lower limit. */
    if ((day < 1) || (month < 1) || (year < 1)) return false;   // <-- EXIT!!

    /* Find out the amount of days in this month */
    if (month == 2) var max_days = daysInFebruary(year);
    else var max_days = daysInMonth[month];

    /* Check for upper limit. */
    if ((day > max_days) || (month > 12)) return false;   // <-- EXIT!!

    return true;
} // checkDate


function checkTime(Time) {
    var result = true;
    var max_hours = 23;
    var max_mins = 59;
    var max_secs = 59;

    Time = Time.toLowerCase();
    if ((Time.indexOf('am') != -1) ||
        (Time.indexOf('pm') != -1)) {
        max_hours = 12;
    }  // if

    Time = replaceNonNumbers(Time);
    var split = Time.split(".");
    var hour = parseInt(split[0]);
    var min = parseInt(split[1]);
    var sec = parseInt(split[2]);

    if ((hour < 0) || (hour > max_hours) ||
        (min < 0) || (min > max_mins) ||
        (sec < 0) || (sec > max_secs)) {
        result = false;
    } // if

    return result;
} // checkTime


function checkDateTime(TimeStamp, Style) {
    var pos = TimeStamp.indexOf(" ");
    var date = TimeStamp.substring(0, pos);
    var time = TimeStamp.substring(pos + 1);

    result = checkDate(date, Style) && checkTime(time);

    return result;
} // checkDateTime


function checkRange(value, range){
    result = true;
    /* Remove braces */
    minmax = range.split(",");
    min = parseFloat(minmax[0]);
    max = parseFloat(minmax[1]);
    value = parseFloat(value);
    if (minmax[0] != "")
        if (value < min) {
            result = false;
        }
    if (minmax[1] != "")
        if (value > max) {
            result = false;
        }

    return result;
} // checkRange()


function checkNumber(value, ranges) {
    adjustField = "";
    result = true;
    rArray = ranges.split("|");
    rCount = rArray.length;
    for (c = 0; c < rCount; c++) {
        num = parseInt(rArray[c].charAt(0));
        if (!isNaN(num)) {
            result = false;
            if (checkRange(value, rArray[c])) {
                return true;
            }
        }
    } // for

    return result;
} // checkNumber()


function adjust(value, ranges) {
    rArray = ranges.split(";");
    rCount = rArray.length;
    for (c = 0; c < rCount; c++) {
        num = parseInt(rArray[c].charAt(0));
        if (!isNaN(num)) {
            range = rArray[c];
            minmax = range.split(",");
            min = parseFloat(minmax[0]);
            max = parseFloat(minmax[1]);
            value = parseFloat(value);
            if (minmax[0] != "")
                if (value < min) {
                    res = min;
                }
            if (minmax[1] != "")
                if (value > max) {
                    res = max;
                }
            return res;              // <-- EXIT!!!!
        } // if
    } // for

    return value;
} // adjust()


function soRound(value, digits) {
    intPart = Math.floor(value);
    fract = value - intPart;
    power = Math.pow(10, digits);
    fract = Math.round(fract * power) /power;
    return intPart + fract;
} //soRound


function adjustDigits(value, ranges) {
    rArray = ranges.split(";");
    result = value;
    if (rArray.length > 1) {
        digits = parseInt(rArray[1]);
        if (isFinite(digits)) {
            value = soRound(value, digits);
        }
    }

    return value;
} // adjustDigits()


function typeCheck(e) {
    fieldName = e.target.name;
    fieldValue = e.target.value;
    fieldTag = extractTag(fieldName);
    typedChar = e.which;
    result = true;
    typeInfo = eval('dzType_'+fieldTag);

    if (typeInfo != 'undefined') {
        typeArr = typeInfo.split(";");
        tCount = typeArr.length;
        if (tCount < 1)
            return true;    // <-- EXIT
        /* Is auto adjust defined? */
        autoAdjust = typeArr[tCount-1] == "A";

        switch (typeArr[0]) {
            case "dec":
                match = new RegExp("^\\s*-?\\d*(\\.|,)?\\d*$");
                result = match.test(fieldValue);
                if (result) {
                    result = checkNumber(fieldValue, typeArr[1]);
                    if ((!result) && (autoAdjust)) {
                        fieldValue = adjust(fieldValue, typeArr[1]);
                        e.target.value = fieldValue;
                        result = true;
                    }
                    // e.target.value = adjustDigits(fieldValue, typeInfo)
                }
                break;

            case "int":
                match = new RegExp("^\\s*-?\\d*$");
                result = match.test(fieldValue);
                if (result) {
                    result = checkNumber(fieldValue, typeArr[1]);
                    if ((!result) && (autoAdjust)) {
                        e.target.value = adjust(fieldValue, typeArr[1]);
                    }
                }
                break;

            case "char":
                if (tCount > 1) {
                    s = typeArr[1];
                    minmax = s.split(",");
                    minLength = parseInt(minmax[0]);
                    maxLength = parseInt(minmax[1]);
                } else {
                    minLength = 0;
                    maxLength = 0;
                }

                if (autoAdjust) {
                    fieldValue = fieldValue.substr(0, maxLength)
                    e.target.value = fieldValue;
                }
                if (maxLength > 0)
                    resultMax = (fieldValue.length <= maxLength);
                else
                    resultMax = true;

                if (minLength > 0)
                    resultMin = (fieldValue.length >= minLength);
                else
                    resultMin = true;
                result = resultMax && resultMin;
                break;

            case "date":
                /* typeArr[1] holds the date type */
                result = checkDate(fieldValue, typeArr[1]);
                break;

            case "time":
                result = checkTime(fieldValue);
                break;

            case "datetime":
            case "dt":
                /* typeArr[1] holds the date type */
                result = checkDateTime(fieldValue, typeArr[1]);
                break;
        } // switch
    } // if
    return result;
}
